#pragma once
#include "FileHandler.h"
#include <d2d1.h>

// forward declaration
struct IDWriteFactory;
struct IDWriteTextLayout;
struct DWRITE_TEXT_RANGE;

class ViewController
{
	ID2D1Factory*	mD2D1Factory;
	ID2D1HwndRenderTarget* mRenderTarget;
	IDWriteFactory* mWriteFactory;
	IDWriteTextFormat* mWriteTextFormat;

	double mDesktopDPIScaleX, mDesktopDPIScaleY;
	FLOAT mMaxWidth;
	FLOAT mLineHeight;
	bool mIsPendingUninitializeComLibrary;

	LONGLONG mSelectionStart;
	LONGLONG mSelectionEnd;
	bool mIsSelectionPresent;
	bool mIsSelectingHexPart;

	LONGLONG mInvalidatedStripTopLine, mInvalidatedStripBottomLine;
	FLOAT mPixelsPerCharacterWidth;
public:
	ViewController();
	~ViewController();

	long double GetContentHeight(const FileHandler&) const;
	double GetLineHeight() const;
	LONGLONG GetAddressForYPosition(long double y);
	long double GetYPositionForAddress(LONGLONG address);
	int CalculateMaxWidth(const FileHandler&);
	bool ClearSelection();
	void StartSelection(int x, LONGLONG y, const FileHandler&);
	void ContinueSelection(int x, LONGLONG y, const FileHandler&, bool useCurrentPart);
	void SelectAll(const FileHandler&);
	void SetSelection(LONGLONG selectionStart, LONGLONG selectionEnd);
	bool IsSelectionPresent() const;
	void GetSelection(LONGLONG& outSelectionStart,
		LONGLONG& outSelectionEnd) const;

	void ResetInvalidatedStrip();
	bool AdjustInvalidatedRect(LONGLONG scrollPosY, RECT& ioRect) const;
	void ExtendInvalidatedStrip();

	bool CreateDeviceIndependentResources();
	bool RecreateRenderTarget(HWND);
	void ResizeRenderTarget(int cx, int cy);
	bool Draw(long double scrollPosY, const RECT& dirtyRect, FileHandler&);

private:
	double GetRawLineHeight() const;

	// returns the number of characters written to text buffer, and also
	// the offset "outFirstDataPosition"
	int GetLineText(LONGLONG address, WCHAR* outTextBuffer, int bufferLength,
		FileHandler&, int& outFirstDataPosition);

	HRESULT HighlightBackground(IDWriteTextLayout*, const DWRITE_TEXT_RANGE&,
		FLOAT y, ID2D1Brush* brush, bool halfSpaceShift);
	
	int ByteOffset(int characterPosition);
	bool IsAtHexPart(int characterPosition);
	int IndexWithinDataString(int x, LONGLONG address0);

};

